package com.tanhua.server.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tanhua.dubbo.server.api.UserLikeApi;
import com.tanhua.dubbo.server.api.UserLocationApi;
import com.tanhua.dubbo.server.pojo.RecommendUser;
import com.tanhua.dubbo.server.pojo.UserLike;
import com.tanhua.dubbo.server.vo.PageInfo;
import com.tanhua.dubbo.server.vo.UserLocationVo;
import com.tanhua.server.enums.SexEnum;
import com.tanhua.server.pojo.Question;
import com.tanhua.server.pojo.User;
import com.tanhua.server.pojo.UserInfo;
import com.tanhua.server.utils.UserThreadLocal;
import com.tanhua.server.vo.NearUserVo;
import com.tanhua.server.vo.PageResult;
import com.tanhua.server.vo.RecommendUserQueryParam;
import com.tanhua.server.vo.TodayBest;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class TodayBestService {
    @Value("${tanhua.sso.url}")
    private String url;

    private static final ObjectMapper MAPPER = new ObjectMapper();

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private RecommendUserService recommendUserService;

    @Autowired
    private UserInfoService userInfoService;

    @Value("${tanhua.sso.default.user}")
    private Long defaultUser;

    @Value("tanhua.sso.default.recommend.users")
    private String defaultRecommendUsers;

    /**
     * 查询今日佳人
     *
     * @param token
     * @return
     */
    public TodayBest queryTodayBest(String token) {
        //1.校验token是否有效，通过SSO的接口进行校验
        //调用业务层userService中的校验token方法queryUserByToken,并传入参数token,返回user对象
        User user = this.userService.queryUserByToken(token);

        //1.2若返回的用户为空,说明token值非法或者已经过期
        if (null == user) {
            //token非法或已经过期
            return null;
        }

        //2.查询推荐用户（今日佳人）
        //2.1通过调用业务层的recommendUserService(推荐用户业务层),调用寻找今日佳人的方法,并且传入上述返回的user对象的id,返回的是todayBest对象
        TodayBest todayBest = this.recommendUserService.queryTodayBest(user.getId());

        //2.2若返回的对象为空,则说明该用户没有匹配的缘分值用户
        if (null == todayBest) {
            //2.3给出默认的推荐用户defaultUser
            todayBest = new TodayBest();
            todayBest.setId(defaultUser);

            //2.4将缘分值设置为固定值
            todayBest.setFateValue(98L); //固定值
        }

        //3.补全今日佳人的个人信息
        //3.1通过调用业务层(userInfoService)的通过用户id查询用户信息的方法,传入今日佳人的id,返回的是今日佳人的信息
        UserInfo userInfo = this.userInfoService.queryUserInfoByUserId(todayBest.getId());

        //3.2若返回的用户信息为空,则返回null
        if (null == userInfo) {
            return null;
        }

        //4.若返回的用户信息不为空,则设置用户的头像,外号,标签(根据','进行分割),性别,年龄
        todayBest.setAvatar(userInfo.getLogo());
        todayBest.setNickname(userInfo.getNickName());
        todayBest.setTags(StringUtils.split(userInfo.getTags(), ','));
        todayBest.setGender(userInfo.getSex().getValue() == 1 ? "man" : "woman");
        todayBest.setAge(userInfo.getAge());

        //5.返回今日佳人对象
        return todayBest;
    }


    /**
     * 查询推荐用户列表
     *
     * @param token
     * @param param
     * @return
     */
    public PageResult queryRecommendation(String token, RecommendUserQueryParam param) {
        //1.校验token
        User user = this.userService.queryUserByToken(token);

        //若返回的user为空,则返回为空
        if (null == user) {
            return null;
        }

        //2.设置一个结果集用来存储分页的条件
        PageResult pageResult = new PageResult();
        pageResult.setPage(param.getPage());
        pageResult.setPagesize(param.getPagesize());


        //3.进行分页查询
        PageInfo<RecommendUser> pageInfo = this.recommendUserService.queryRecommendUserList(
                user.getId(), param.getPage(), param.getPagesize());

        //3.1获取到数据列表
        List<RecommendUser> records = pageInfo.getRecords();

        //3.2若没有查询到推荐用户列表
        if (CollectionUtils.isEmpty(records)) {
            /**
             * 默认推荐列表
             */
            //3.3 推荐用户id根据","进行分割
            String[] ss = StringUtils.split(defaultRecommendUsers, ",");
            for (String s : ss) {
                //3.4 创建一个推荐用户对象
                RecommendUser recommendUser = new RecommendUser();

                //3,5 设置推荐用户的id
                recommendUser.setUserId(Long.valueOf(s));

                //3.6 设置被推荐用户id,就是当前用户
                recommendUser.setToUserId(user.getId());

                //3.7 设置随机分数
                recommendUser.setScore(RandomUtils.nextDouble(70d, 99d));

                records.add(recommendUser);
            }
        }


        //4.填充个人信息
        //4.1收集推荐用户id
        Set<Long> userIds = new HashSet<>();
        for (RecommendUser record : records) {
            userIds.add(record.getUserId());
        }

        //4.2查询条件
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();

        //4.2.1用户id
        queryWrapper.in("user_id", userIds);

       /* //4.2.3筛选条件
        if(StringUtils.isNotEmpty(param.getGender())){
            queryWrapper.eq("sex",StringUtils.equals(param.getGender(),"man") ? 1:2);
        }

        if(StringUtils.isNotEmpty(param.getCity())){
            queryWrapper.like("city",param.getCity());
        }

        if (param.getAge() != null){
            queryWrapper.le("age",param.getAge());
        }*/

        //5.从数据库中查询推荐用户的信息
        List<UserInfo> userInfoList = this.userInfoService.queryUserInfoList(queryWrapper);
        if (CollectionUtils.isEmpty(userInfoList)) {
            return pageResult;
        }

        //5.1填充推荐用户的信息
        List<TodayBest> todayBests = new ArrayList<>();

        //5.2遍历查询出来的用户信息进行填充
        for (UserInfo userInfo : userInfoList) {
            TodayBest todayBest = new TodayBest();

            todayBest.setAvatar(userInfo.getLogo());
            todayBest.setId(userInfo.getUserId());
            todayBest.setGender(userInfo.getSex().getValue() == 1 ? "man" : "woman");
            todayBest.setAge(userInfo.getAge());
            todayBest.setTags(userInfo.getTags().split(","));
            todayBest.setNickname(userInfo.getNickName());

            //5.3填充缘分值
            for (RecommendUser record : records) {
                if (record.getUserId().longValue() == userInfo.getUserId().longValue()) {
                    double score = Math.floor(record.getScore());
                    todayBest.setFateValue(Double.valueOf(score).longValue());
                    break;
                }
            }
            todayBests.add(todayBest);
        }


        //6.缘分值进行降序排序
        Collections.sort(todayBests, ((o1, o2) -> new Long(o2.getFateValue() - o1.getFateValue()).intValue()));

        //6.1设置返回值中的列表参数
        pageResult.setItems(todayBests);

        //6.3返回
        return pageResult;
    }


    /**
     * 今日佳人详细信息
     *
     * @param userId
     * @return
     */
    public TodayBest queryTodayBest(Long userId) {
        User user = UserThreadLocal.get();

        TodayBest todayBest = new TodayBest();

        //补全今日佳人信息
        UserInfo userInfo = this.userInfoService.queryUserInfoByUserId(userId);
        todayBest.setId(userId);
        todayBest.setAge(userInfo.getAge());
        todayBest.setAvatar(userInfo.getLogo());
        todayBest.setGender(userInfo.getSex().name().toLowerCase());
        todayBest.setNickname(userInfo.getNickName());
        todayBest.setTags(StringUtils.split(userInfo.getTags(), ","));


        //设置分数
        double score = this.recommendUserService.queryScore(userId, user.getId());
        if (score == 0) {
            score = 98; //默认分值
        }

        //设置缘分值
        todayBest.setFateValue(Double.valueOf(score).longValue());

        return todayBest;
    }

    @Autowired
    private QuestionService questionService;
    /**
     * 查询陌生人问题
     * @param userId
     * @return
     */
    public String queryQuestion(Long userId) {
        //从数据库中查询数据
        Question question = this.questionService.queryQuestion(userId);

        //若查到数据,获取问题
        if (null != question){
            return question.getTxt();
        }

        //否则返回空字符串
        return "";
    }

    /**
     * 回复陌生人问题,发送消息给对方
     * @param userId
     * @param reply
     * @return
     */
    public Boolean replyQuestion(Long userId, String reply) {
        User user = UserThreadLocal.get();
        UserInfo userInfo = this.userInfoService.queryUserInfoByUserId(user.getId());

        //构建消息内容,封装要查询信息
        Map<String,Object> msg = new HashMap<>();
        msg.put("userId",user.getId().toString());
        msg.put("nickname",userInfo.getNickName());
        msg.put("strangerQuestion",this.queryQuestion(userId));
        msg.put("reply",reply);

        try {
            //变成字符串
            String msgStr = MAPPER.writeValueAsString(msg);

            //封装请求路径
            String targetUrl = this.url + "/user/huanxin/messages";

            //请求头信息
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            MultiValueMap<String,String> params = new LinkedMultiValueMap<>();
            params.add("target",userId.toString());
            params.add("msg",msgStr);

            HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(params, headers);

            ResponseEntity<Void> responseEntity = this.restTemplate.postForEntity(targetUrl, httpEntity, Void.class);

            return responseEntity.getStatusCodeValue() == 200;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return false;
    }

    @Reference(version = "1.0.0") //2.0.0是es服务,1.0.0是mongodb服务
    private UserLocationApi userLocationApi;
    /**
     * 搜附近
     * @param gender
     * @param distance
     * @return
     */
    public List<NearUserVo> queryNearUser(String gender, String distance) {
        User user = UserThreadLocal.get();

        //查看当前用户的位置信息
        UserLocationVo userLocationVo = this.userLocationApi.queryByUserId(user.getId());
        Double longitude = userLocationVo.getLongitude();
        Double latitude = userLocationVo.getLatitude();

        //根据当前的位置信息查询附近的好友
        List<UserLocationVo> userLocationList = this.userLocationApi.queryUserFromLocation(longitude, latitude, Integer.valueOf(distance));

        //查询为空,返回空集合
        if (CollectionUtils.isEmpty(userLocationList)){
            return Collections.emptyList();
        }

        //好友的id集合
        List<Long> userIds = new ArrayList<>();
        for (UserLocationVo locationVo : userLocationList) {
            userIds.add(locationVo.getUserId());
        }

        //根据条件进行查询
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("user_id",userIds);
        if(StringUtils.equalsIgnoreCase(gender,"man")){
            queryWrapper.in("sex", SexEnum.MAN);
        }else {
            queryWrapper.in("sex",SexEnum.WOMAN);
        }

        //从数据库中查询好友信息
        List<UserInfo> userInfoList = this.userInfoService.queryUserInfoList(queryWrapper);

        //排除自己
        List<UserInfo> filterUsers = userInfoList.stream().filter(s -> !s.getUserId().equals(user.getId())).collect(Collectors.toList());

        //将查询到的信息添加到返回列表中
        List<NearUserVo> nearUserVoList = new ArrayList<>();
        for (UserInfo filterUser : filterUsers) {
            NearUserVo nearUserVo = new NearUserVo();
            nearUserVo.setUserId(filterUser.getUserId());
            nearUserVo.setNickname(filterUser.getNickName());
            nearUserVo.setAvatar(filterUser.getLogo());

            nearUserVoList.add(nearUserVo);
        }
        return nearUserVoList;
    }

    /**
     * 探花(卡片功能)
     * @return
     */
    public List<TodayBest> queryCardsList() {
        User user = UserThreadLocal.get();
        int count = 50;

        PageInfo<RecommendUser> pageInfo = this.recommendUserService.queryRecommendUserList(user.getId(), 1, count);
        if (CollectionUtils.isEmpty(pageInfo.getRecords())){
            //默认推荐列表
            String[] ss = StringUtils.split(defaultRecommendUsers, ",");
            for (String s : ss) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Long.valueOf(s));
                recommendUser.setToUserId(user.getId());
                pageInfo.getRecords().add(recommendUser);
            }
        }

        List<RecommendUser> records = pageInfo.getRecords();
        //定义要展示的页数
        int showCount = Math.min(10,records.size());

        //将数据进行打散
        Collections.shuffle(records);

        //随机选出推荐好友,选择前几条
        List<RecommendUser> newRecommendUserList = records.subList(0,showCount);


        //获取推荐好友的id
        List<Long> userIds = new ArrayList<>();
        for (RecommendUser recommendUser : newRecommendUserList) {
            userIds.add(recommendUser.getUserId());
        }

        //查询条件
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("user_id",userIds);

        List<UserInfo> userInfoList = this.userInfoService.queryUserInfoList(queryWrapper);
        List<TodayBest> todayBests = new ArrayList<>();
        for (UserInfo userInfo : userInfoList) {
            TodayBest todayBest = new TodayBest();
            todayBest.setId(userInfo.getUserId());
            todayBest.setAge(userInfo.getAge());
            todayBest.setAvatar(userInfo.getLogo());
            todayBest.setGender(userInfo.getSex().name().toLowerCase());
            todayBest.setNickname(userInfo.getNickName());
            todayBest.setTags(StringUtils.split(userInfo.getTags(),","));
            todayBest.setFateValue(0L);

            todayBests.add(todayBest);
        }
        return todayBests;

    }

    @Reference(version = "1.0.0")
    private UserLikeApi userLikeApi;

    @Autowired
    private IMService imService;

    /**
     * 喜欢
     * @param likeUserId
     */
    public Boolean likeUser(Long likeUserId) {
        User user = UserThreadLocal.get();

        //1.通过mongodb保存喜欢
        String id = this.userLikeApi.saveUserLike(user.getId(), likeUserId);

        //2.判断是否保存成功
        if (StringUtils.isEmpty(id)){
            return false;
        }

        //3.判断是否相互喜欢,若相互喜欢,则成为好友
        if (this.userLikeApi.isMutualLike(user.getId(),likeUserId)){
            this.imService.contactUser(likeUserId);
        }
        return true;
    }

    /**
     * 不喜欢
     * @param likeUserId
     */
    public Boolean disLikeUser(Long likeUserId) {
        User user = UserThreadLocal.get();
        return this.userLikeApi.deleteUserLike(user.getId(),likeUserId);
    }
}
